package com.sinodata.bsm.cicp.collector.sybase;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.AbstractJDBCCollector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.common.constants.SeparatorConstants;
import com.sinodata.bsm.common.vo.ResPropertyValue;

public class Locks extends AbstractJDBCCollector {

    private static final Logger logger = Logger.getLogger(Locks.class);

    /**
     * 采集方法
     * @param pParmeters Sybase Locks资源的属性值数组:锁信息
     * @return session,
     */

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        try {
            String[] propMetas = getPropMeta();
            //        String serverName = this.getParamMap().get("服务器名");
            String serverName = this.getParamMap().get("ServerName");
            System.out.println("serverName:" + serverName);
            String sql = "   SELECT                                                                                                                   "
            // display all locks
            + "   spid=syslocks.spid,                                                                                                           " + "   pid=sysprocesses.hostprocess,                                                                                            " + "   userid=substring(sysusers.name,1,7),                                                                                     " + "   dbname=substring(db_name(syslocks.dbid), 1, 15),                                                                         " + "   table_blcked_by=convert(varchar(17),isnull(object_name(syslocks.id, syslocks.dbid),convert(varchar(30),syslocks.id))),   " + "   lock_type=convert(varchar(14),spt_values.name),                                                                          " + "   page=convert(varchar(10),syslocks.page),                                                                                 " + "   status=substring(sysprocesses.status, 1, 10),                                                                            " + "   time_blocked=isnull(sysprocesses.time_blocked, 0) ,                                                                       " + "   program=substring(program_name,1,15),                                                                                    " + "   command=substring(cmd,1,128)                                                                                             " + "   FROM master.dbo.syslocks  syslocks,                                                                                      " + "        master.dbo.spt_values spt_values,                                                                                   " + "        master.dbo.sysprocesses sysprocesses,                                                                               " + "        master.dbo.syslogins sysusers                                                                                       " + "   WHERE syslocks.type = spt_values.number                                                                                  " + "        and spt_values.type = 'L'                                                                                           " + "        and syslocks.spid = sysprocesses.spid                                                                               " + "        and sysusers.suid = sysprocesses.suid                                                                               " + "   UNION                                                                                                                    " + "    SELECT                                                                                                                  " + "    spid=sp1.spid,                                                                                                               " + "    pid=sp1.hostprocess,                                                                                                    " + "    userid=substring(suser_name(sp1.suid),1,7),                                                                             " + "    dbname= substring(db_name(sp1.dbid),1,15),                                                                              " + "    table_blcked_by=convert(char(3),sp1.blocked) + substring(suser_name(sp2.suid),1,14),                                    " + "    lock_type='',                                                                                                            " + "    page='',                                                                                                                " + "    status=substring(sp1.status, 1, 10),                                                                                    " + "    time_blocked=isnull(sp1.time_blocked, 0) ,                                                                              " + "    program=substring(sp1.program_name,1,15),                                                                               " + "    command=substring(sp1.cmd,1,128)                                                                                        " + "    FROM master.dbo.sysprocesses sp1, master.dbo.sysprocesses sp2                                                           " + "    WHERE sp1.blocked = sp2.spid";

            String[] rs = this.getStrings(serverName, sql, ip);
            ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
            for (int i = 0; i < propMetas.length; i++) {
                propValues[i] = ResPropertyValue.createPropValue(rs[i], propMetas[i]);
            }
            propertyValueX.setValues(propValues);
            values.add(propertyValueX);
        } catch (Exception ex) {
            logger.error("failed to collect sybase locks", ex);
            throw new CollectorException(ex);
        }
        return values;
    }

    private String[] getStrings(String serverName, String sql, String ip) throws CollectorException {
        String[] propValArr = new String[1];
        try {

            ResultSet rst = this.getCachedResultSet("sybase", ip, serverName, sql);
            if (rst != null) {
                StringBuffer sessions = new StringBuffer("");
                //会话ID|进程ID|用户|数据库名|锁内容|锁类型|页|状态|阻塞时间(秒)|程序|命令
                //                sessions.append("Session ID").append(SeparatorConstants.COL_SEPARATOR);//会话ID
                //                sessions.append("Process ID").append(SeparatorConstants.COL_SEPARATOR);//进程ID
                //                sessions.append("User").append(SeparatorConstants.COL_SEPARATOR);//用户
                //                sessions.append("Database Name").append(SeparatorConstants.COL_SEPARATOR);//数据库名
                //                sessions.append("Lock Content").append(SeparatorConstants.COL_SEPARATOR);//锁内容
                //                sessions.append("Lock Type").append(SeparatorConstants.COL_SEPARATOR);//锁类型
                //                sessions.append("Page").append(SeparatorConstants.COL_SEPARATOR);//页
                //                sessions.append("Status").append(SeparatorConstants.COL_SEPARATOR);//状态
                //                sessions.append("Choke Time(s)").append(SeparatorConstants.COL_SEPARATOR);//阻塞时间(秒)
                //                sessions.append("Program").append(SeparatorConstants.COL_SEPARATOR);//程序
                //                sessions.append("Command").append(SeparatorConstants.COL_SEPARATOR).append(SeparatorConstants.LIN_SEPARATOR);//命令
                while (rst.next()) {
                    String line = getTabLineStr(rst, 11);
                    sessions.append(line).append(SeparatorConstants.LIN_SEPARATOR);
                }
                String configureInfostr = sessions.toString();
                propValArr[0] = configureInfostr;
            } else {
                return null;
            }

        } catch (Exception ex) {
            logger.error("while connect database : ", ex);
            throw new CollectorException(ex);
        }

        return propValArr;
    }

    private String getTabLineStr(ResultSet rst, int colNum) throws CollectorException {
        StringBuffer tabLineStr = new StringBuffer();
        try {
            for (int i = 1; i <= colNum; i++) {
                String val = rst.getString(i);
                if (val == null || val.trim().length() == 0) {
                    val = " ";
                } else
                    val = val.trim();
                tabLineStr.append(val).append(SeparatorConstants.COL_SEPARATOR);
            }
        } catch (Exception e) {
            logger.error("failed to get TabLineStr", e);
            throw new CollectorException(e);
        }
        return tabLineStr.toString();
    }

    @Override
    public String[] getParamMeta() {
        //        return new String[] { "服务器名" };
        return new String[] { "ServerName" };
    }

    @Override
    public String[] getPropMeta() {
        //        return new String[] { "锁信息" };
        return new String[] { "LockInfo" };
    }
}
